﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Smugmug.Tests
{
    public class TestWebClient : IWebClient
    {
        private WebRequestCollection requests = new WebRequestCollection();
        public static readonly string ValueWildCard = "*";
        public static readonly string KeyWildCard = "!";

        public TestWebClient()
        {
            requests = SerializationHelper.DeserializeXml<WebRequestCollection>(Resources.requests);
        }

        #region IWebClient Members

        public string MakeRequest(Uri url)
        {
            foreach (var request in requests)
            {
                if (IsMatch(url, new Uri(request.Url)))
                {
                    return request.Response;
                }
            }
            throw new ArgumentOutOfRangeException("url", String.Format("The url '{0}' was not found in the known requests", url));
        }

        #endregion

        public static bool IsMatch(Uri url, Uri patternUrl)
        {
            if (url == patternUrl)
                return true;

            if (url.Scheme != patternUrl.Scheme ||
                url.Host != patternUrl.Host ||
                url.AbsolutePath != patternUrl.AbsolutePath)
                return false;

            if (url.Query.Contains(ValueWildCard) || url.Query.Contains(KeyWildCard))
                throw new ArgumentOutOfRangeException("The source Url can't contain any wildcards");

            if (patternUrl.Query.Contains(ValueWildCard) || patternUrl.Query.Contains(KeyWildCard))
            {
                var urlPairs = new QueryStringHelper(url);
                var patternPairs = new QueryStringHelper(patternUrl);

                //Remove All Optional Parameters from the url
                IEnumerable<string> optionalParameters =
                    from p in patternPairs
                    where p.Key.EndsWith(KeyWildCard)
                    select p.Key.Replace(KeyWildCard, "");
                foreach (string key in optionalParameters)
                {
                    urlPairs.Remove(key);
                    patternPairs.Remove(key + KeyWildCard);
                }

                if (urlPairs.Count != patternPairs.Count)
                    return false;

                //Now check for wilcards in the values
                foreach (var pair in urlPairs)
                {
                    if (!patternPairs.ContainsKey(pair.Key))
                        return false;

                    var pattern = patternPairs[pair.Key];
                    if (pattern != ValueWildCard && pattern != pair.Value)
                    {
                        return false;
                    }
                }
                return true;
            }
            else
            {
                //Note: Should never get here
                return url.Query == patternUrl.Query;
            }
        }
    }
}